home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Atari Compendium
/
The Atari Compendium (Toad Computers) (1994).iso
/
files
/
umich
/
network
/
mail
/
pathalia.zoo
/
src
/
arpatxt.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-01-12
|
13KB
|
683 lines
#ifndef lint
static char *sccsid = "@(#)arpatxt.c 9.4 88/09/21";
#endif
/*
* convert hosts.txt into pathalias format.
*
* alias rule: "host.dom.ain,nickname.arpa,..." -> host = nickname, ...
*/
/* remove the next line for standard or research unix */
#define BSD
#ifdef BSD
#define strchr index
#endif /* BSD */
#include <stdio.h>
#include <ctype.h>
/* imports */
extern char *re_comp(), *malloc(), *strchr(), *calloc();
extern char *gets(), *strcpy(), *fgets();
extern FILE *fopen();
typedef struct node node;
struct node {
node *child; /* subdomain or member host */
node *parent; /* parent domain */
node *next; /* sibling in domain tree or host list */
char *name; /* host name */
node *alias; /* list of aliases */
node *bucket;
node *gateway;
int flag;
};
node *Top;
int Atflag, Fflag, Iflag, Vflag;
char *DotArpa = ".ARPA";
char Fname[256], *Fstart;
node *newnode(), *find();
char *strsave(), *lowercase();
void crcinit();
long fold();
FILE *mkfile();
int insert();
#define ISADOMAIN(n) ((n) && *((n)->name) == '.')
/* for node.flag */
#define COLLISION 1
/* for formatprint() */
#define PRIVATE 0
#define HOSTS 1
#define SUBDOMAINS 2
/* for usage() */
#define USAGE "usage: %s [-i@] [-g gateway] [-p privatefile] [-f | -d directory] [file ...]\n"
main(argc, argv)
char **argv;
{ int c;
char *progname;
extern char *optarg;
extern int optind;
if ((progname = strchr(argv[0], '/')) != 0)
progname++;
else
progname = argv[0];
crcinit();
Top = newnode(); /* needed for adding gateways */
while ((c = getopt(argc, argv, "d:fg:ip:v@")) != EOF)
switch(c) {
case 'd':
strcpy(Fname, optarg);
break;
case 'f': /* filter mode -- write on stdout */
Fflag++;
break;
case 'g':
gateway(optarg);
break;
case 'i':
Iflag++;
break;
case 'p':
readprivates(optarg);
break;
case 'v':
Vflag++;
break;
case '@':
Atflag++;
break;
default:
usage(progname);
}
if (Fflag && *Fname)
usage(progname);
if (Iflag)
(void) lowercase(DotArpa);
if (Top->gateway == 0)
fprintf(stderr, "%s: warning: no gateway to top level domains\n", progname);
Fstart = Fname + strlen(Fname);
if (Fstart != Fname) {
*Fstart++ = '/';
*Fstart = 0;
}
/* should do the mkdir here instead of the shell script ...*/
Top->name = "internet";
if (optind == argc)
scan();
else for ( ; optind < argc; optind++) {
if (freopen(argv[optind], "r", stdin) == 0) {
perror(argv[optind]);
continue;
}
scan();
}
setuniqflag(Top); /* look for and mark collisions */
hashanalyze(); /* check hash algorithm performance */
merge(); /* make unique domain names */
dump(Top); /* print */
return 0;
}
scan()
{ static first;
char buf0[BUFSIZ], buf1[BUFSIZ], buf2[BUFSIZ];
if (first++ == 0)
(void) re_comp("^HOST.*SMTP");
while (gets(buf0) != 0) {
if (re_exec(buf0) == 0)
continue;
if (sscanf(buf0, "HOST : %[^:] : %[^: ]", buf1, buf2) != 2)
continue;
if (Iflag)
(void) lowercase(buf2);
if (insert(buf2) != 0)
fprintf(stderr, "input error: %s\n", buf0);
}
}
/*
* format of private file:
* one per line, optionally followed by white space and comments
* line starting with # is comment
*/
readprivates(pfile)
char *pfile;
{ FILE *f;
node *n;
char buf[BUFSIZ], *bptr;
if ((f = fopen(pfile, "r")) == 0) {
perror(pfile);
return;
}
while (fgets(buf, BUFSIZ, f) != 0) {
if (*buf == '#')
continue;
if ((bptr = strchr(buf, ' ')) != 0)
*bptr = 0;
if ((bptr = strchr(buf, '\t')) != 0)
*bptr = 0;
if (*buf == 0)
continue;
n = newnode();
n->name = strsave(buf);
hash(n);
}
(void) fclose(f);
}
usage(progname)
char *progname;
{
fprintf(stderr, USAGE, progname);
exit(1);
}
dumpgateways(ndom, f)
node *ndom;
FILE *f;
{ node *n;
for (n = ndom->gateway; n; n = n->next) {
fprintf(f, "%s ", n->name);
if (Atflag)
putc('@', f);
fprintf(f, "%s(%s)\t# gateway\n", ndom->name,
ndom == Top ? "DEDICATED" : "LOCAL");
}
}
gateway(buf)
char *buf;
{ node *n, *dom;
char *dot;
dot = strchr(buf, '.');
if (dot) {
dom = find(dot);
*dot = 0;
} else
dom = Top;
n = newnode();
n->name = strsave(buf);
n->next = dom->gateway;
dom->gateway = n;
}
int
insert(buf)
char *buf;
{ char host[BUFSIZ], *hptr, *dot;
node *n;
for (hptr = host; *hptr = *buf++; hptr++)
if (*hptr == ',')
break;
if (*hptr == ',')
*hptr = 0;
else
buf = 0; /* no aliases */
if ((dot = strchr(host, '.')) == 0)
return 1; /* can't happen */
if (strcmp(dot, DotArpa) == 0)
buf = 0; /* no aliases */
n = find(dot);
*dot = 0;
addchild(n, host, buf);
return 0;
}
node *
find(domain)
char *domain;
{ char *dot;
node *parent, *child;
if (domain == 0)
return Top;
if ((dot = strchr(domain+1, '.')) != 0) {
parent = find(dot);
*dot = 0;
} else
parent = Top;
for (child = parent->child; child; child = child->next)
if (strcmp(domain, child->name) == 0)
break;
if (child == 0) {
child = newnode();
child->next = parent->child;
parent->child = child;
child->parent = parent;
child->name = strsave(domain);
}
return child;
}
node *
newnode()
{
node *n;
if ((n = (node *) calloc(1, sizeof(node))) == 0)
abort();
return n;
}
char *
strsave(buf)
char *buf;
{ char *mstr;
if ((mstr = malloc(strlen(buf)+1)) == 0)
abort();
strcpy(mstr, buf);
return mstr;
}
addchild(n, host, aliases)
node *n;
char *host, *aliases;
{ node *child;
/* check for dups? nah! */
child = newnode();
child->name = strsave(host);
child->parent = n;
child->next = n->child;
makealiases(child, aliases);
n->child = child;
}
/* yer basic tree walk to make output */
dump(n)
node *n;
{ node *child;
FILE *f;
int privates;
/* sanity check */
if (n != Top && ! ISADOMAIN(n))
abort();
f = mkfile(n); /* prepare the output file */
privates = domprint(n, f); /* print this domain */
dumpgateways(n, f); /* print any gateways to this domain */
if (privates || n == Top)
fputs("private {}\n", f); /* end scope of privates */
if (Fflag)
putc('\n', f);
else
(void) fclose(f);
for (child = n->child; child; child = child->next)
if (child->child)
dump(child);
}
qcmp(a, b)
node **a, **b;
{
return strcmp((*a)->name, (*b)->name);
}
domprint(n, f)
node *n;
FILE *f;
{ node *table[8191], *child, *alias;
char *cost = 0;
int nelem, i, privates = 0;
/*
* dump private definitions.
* sort hosts and aliases for pretty output.
*/
if (n != Top) {
i = 0;
for (child = n->child; child; child = child->next) {
table[i++] = child;
for (alias = child->alias; alias; alias = alias->next)
table[i++] = alias;
}
qsort((char *) table, i, sizeof(table[0]), qcmp);
privates = formatprint(f, table, i, PRIVATE, "private", cost);
}
/* dump domains and aliases, sorted for pretty output */
i = 0;
for (child = n->child; child; child = child->next)
table[i++] = child;
qsort((char *) table, i, sizeof(table[0]), qcmp);
/* cost is DEDICATED for hosts in top-level domains, LOCAL o.w. */
if (n->parent == Top && strchr(n->name + 1, '.') == 0)
cost = "DEDICATED";
else
cost = "LOCAL";
(void) formatprint(f, table, i, HOSTS, n->name, cost);
(void) formatprint(f, table, i, SUBDOMAINS, n->name, "0");
/* dump aliases */
nelem = i;
for (i = 0; i < nelem; i++) {
if ((alias = table[i]->alias) == 0)
continue;
fprintf(f, "%s = %s", table[i]->name, alias->name);
for (alias = alias->next; alias; alias = alias->next)
fprintf(f, ", %s", alias->name);
putc('\n', f);
}
return privates;
}
int
formatprint(f, table, nelem, type, lhs, cost)
FILE *f;
node **table;
char *lhs, *cost;
{ int i, didprint;
char buf[128], *bptr;
sprintf(buf, "%s%s{" /*}*/, lhs, type == PRIVATE ? " " : " = ");
bptr = buf + strlen(buf);
didprint = 0;
for (i = 0; i < nelem; i++) {
if (type == PRIVATE && ! (table[i]->flag & COLLISION))
continue;
else if (type == HOSTS && ISADOMAIN(table[i]) )
continue;
else if (type == SUBDOMAINS && ! ISADOMAIN(table[i]) )
continue;
if ((bptr - buf) + strlen(table[i]->name) > 69) {
*bptr = 0;
fprintf(f, "%s\n ", buf); /* continuation */
bptr = buf;
}
sprintf(bptr, "%s, ", table[i]->name);
bpt